package com.example.camerastudy.slice;

import com.example.camerastudy.utils.LogUtils;
import com.example.camerastudy.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.Component;
import ohos.agp.components.surfaceprovider.SurfaceProvider;
import ohos.agp.graphics.Surface;
import ohos.agp.graphics.SurfaceOps;
import ohos.agp.window.service.DisplayManager;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.media.camera.CameraKit;
import ohos.media.camera.device.Camera;
import ohos.media.camera.device.CameraConfig;
import ohos.media.camera.device.CameraStateCallback;
import ohos.media.camera.device.FrameConfig;
import ohos.media.common.AudioProperty;
import ohos.media.common.Source;
import ohos.media.common.StorageProperty;
import ohos.media.common.VideoProperty;
import ohos.media.recorder.Recorder;

import java.io.File;
import java.util.UUID;

import static ohos.media.camera.device.Camera.FrameConfigType.FRAME_CONFIG_RECORD;

/**
 * @author : frank
 * @date : 2021/2/28 18:27
 */
public class RecordSlice extends AbilitySlice {
    HiLogLabel hiLogLabel = new HiLogLabel(3, 3, "录像日志");

    private String TAG = getClass().getSimpleName();

    private Source source; // 音视频源
    private AudioProperty.Builder audioPropertyBuilder; // 音频属性
    private VideoProperty.Builder videoPropertyBuilder; // 视频属性
    private StorageProperty.Builder storagePropertyBuilder; // 音视频存储属性
    private Recorder mediaRecorder; // 录像操作对象
    private String recordName; // 音视频文件名
    private Surface previewSurface;
    private SurfaceProvider surfaceProvider;
    private Camera mCamera;

    private void initMediaRecorder() {
        videoPropertyBuilder = new VideoProperty.Builder();
        audioPropertyBuilder = new AudioProperty.Builder();
        storagePropertyBuilder = new StorageProperty.Builder();
        mediaRecorder = new Recorder();
        source = new Source();
        videoPropertyBuilder.setRecorderBitRate(10000000); // 设置录制比特率
        int rotation = DisplayManager.getInstance().getDefaultDisplay(this).get().getRotation();
        videoPropertyBuilder.setRecorderDegrees(rotation); // 设置录像方向
        videoPropertyBuilder.setRecorderFps(30); // 设置录制采样率
        videoPropertyBuilder.setRecorderHeight(1080); // 设置录像支持的分辨率，需保证width > height
        videoPropertyBuilder.setRecorderWidth(1920);
        videoPropertyBuilder.setRecorderVideoEncoder(Recorder.VideoEncoder.DEFAULT); // 设置视频编码方式
        videoPropertyBuilder.setRecorderRate(30); // 设置录制帧率
        source.setRecorderAudioSource(Recorder.AudioSource.MIC); // 设置录制音频源
        source.setRecorderVideoSource(Recorder.VideoSource.SURFACE); // 设置视频窗口
        mediaRecorder.setSource(source); // 设置音视频源
        mediaRecorder.setOutputFormat(Recorder.OutputFormat.MPEG_4); // 设置音视频输出格式
        StringBuffer fileName = new StringBuffer("record_"); // 生成随机文件名
        fileName.append(UUID.randomUUID()).append(".mp4");
        recordName = fileName.toString();
        File file = new File(getCacheDir(), fileName.toString()); // 创建录像文件对象
        storagePropertyBuilder.setRecorderFile(file); // 设置存储音视频文件名
        mediaRecorder.setStorageProperty(storagePropertyBuilder.build());
        audioPropertyBuilder.setRecorderAudioEncoder(Recorder.AudioEncoder.AAC); // 设置音频编码格式
        mediaRecorder.setAudioProperty(audioPropertyBuilder.build()); // 设置音频属性
        mediaRecorder.setVideoProperty(videoPropertyBuilder.build()); // 设置视频属性
        mediaRecorder.prepare(); // 准备录制
        HiLog.error(hiLogLabel, "initMediaRecorder end");
    }

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_slice_record);

        getWindow().setTransparent(true);
        getWindow().setBackgroundColor(new RgbColor(0xffffffff));

        surfaceProvider = (SurfaceProvider) findComponentById(ResourceTable.Id_surfaceProvider);
        surfaceProvider.getSurfaceOps().get().addCallback(new SurfaceOps.Callback() {
            @Override
            public void surfaceCreated(SurfaceOps surfaceOps) {
                previewSurface = surfaceOps.getSurface();
                initMediaRecorder();
                initCamera();
            }

            @Override
            public void surfaceChanged(SurfaceOps surfaceOps, int i, int i1, int i2) {

            }

            @Override
            public void surfaceDestroyed(SurfaceOps surfaceOps) {

            }
        });

        findComponentById(ResourceTable.Id_button_start_record).setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                HiLog.error(hiLogLabel, "开始录制");
                if (mediaRecorder != null) {
                    mediaRecorder.start();
                }
            }
        });

        findComponentById(ResourceTable.Id_button_stop_record).setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                HiLog.error(hiLogLabel, "结束录制");
                if (mediaRecorder != null) {
                    mediaRecorder.stop();
                }
            }
        });
    }

    CameraStateCallback cameraStateCallback = new CameraStateCallback() {
        @Override
        public void onCreated(Camera camera) {
            super.onCreated(camera);
            mCamera = camera;
            CameraConfig.Builder cameraConfigBuilder = camera.getCameraConfigBuilder();
            if (cameraConfigBuilder == null) {
                LogUtils.info(TAG, "onCreated cameraConfigBuilder is null");
                return;
            }
            // 配置预览的Surface
            cameraConfigBuilder.addSurface(previewSurface);
            cameraConfigBuilder.addSurface(mediaRecorder.getVideoSurface());
            try {
                // 相机设备配置
                camera.configure(cameraConfigBuilder.build());
            } catch (IllegalArgumentException e) {
                LogUtils.info(TAG, "Argument Exception");
            } catch (IllegalStateException e) {
                LogUtils.info(TAG, "State Exception");
            }
        }

        @Override
        public void onCreateFailed(String cameraId, int errorCode) {
            super.onCreateFailed(cameraId, errorCode);
        }

        @Override
        public void onConfigured(Camera camera) {
            super.onConfigured(camera);
            // 获取预览配置模板
            FrameConfig.Builder frameConfigBuilder = camera.getFrameConfigBuilder(FRAME_CONFIG_RECORD);
            // 配置预览Surface
            frameConfigBuilder.addSurface(previewSurface);
            // 配置录像的Surface
            Surface mRecorderSurface = mediaRecorder.getVideoSurface();
            frameConfigBuilder.addSurface(mRecorderSurface);
            FrameConfig previewFrameConfig = frameConfigBuilder.build();
            try {
                // 启动循环帧捕获
                int triggerId = camera.triggerLoopingCapture(previewFrameConfig);

            } catch (IllegalArgumentException e) {
                HiLog.error(hiLogLabel, "Argument Exception");
            } catch (IllegalStateException e) {
                HiLog.error(hiLogLabel, "State Exception");
            }
        }

        @Override
        public void onPartialConfigured(Camera camera) {
            super.onPartialConfigured(camera);
        }

        @Override
        public void onConfigureFailed(Camera camera, int errorCode) {
            super.onConfigureFailed(camera, errorCode);
        }

        @Override
        public void onReleased(Camera camera) {
            super.onReleased(camera);
        }

        @Override
        public void onFatalError(Camera camera, int errorCode) {
            super.onFatalError(camera, errorCode);
        }

        @Override
        public void onCaptureRun(Camera camera) {
            super.onCaptureRun(camera);
        }

        @Override
        public void onCaptureIdle(Camera camera) {
            super.onCaptureIdle(camera);
        }
    };

    private void initCamera() {
        String[] ids = CameraKit.getInstance(this).getCameraIds();
        CameraKit.getInstance(this).createCamera(ids[0], cameraStateCallback, new EventHandler(EventRunner.getMainEventRunner()));
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (surfaceProvider != null){
            surfaceProvider.removeFromWindow();
            surfaceProvider = null;
        }
        if (mCamera != null) {
            // 关闭相机和释放资源
            mCamera.release();
            mCamera = null;
        }
        if (mediaRecorder != null) {
            mediaRecorder.release();
            mediaRecorder = null;
        }
    }

}
